#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <logbase.h>

/*
二维数组与数组指针！
把他们当做一维数组来理解即可。
二维数组首先他是一维数组，一维数组的每一个元素为一个数组！
数组指针也一样（指向数组的指针），指针指向的连续内存的每一个元素是数组。
*/

// 因为函数addFunction定义在调用函数main之前，因此不用声明也可以
//  int addFunction(int a, int b);
int main(int argc, char **argv)
{
#define MY_CHECK_ROWS 3
#define MY_CHECK_COLS 2
    // 二维数组。
    // MY_CHECK_ROWS是行数。
    // MY_CHECK_COLS每行的列数！
    int tmparr[MY_CHECK_ROWS][MY_CHECK_COLS];
    // 数组指针。
    // 数组指针的元素是数组，必须规定数组的长度，不然操作内存时，无法确认指针元素的长度。
    int (*tmpptr)[MY_CHECK_COLS] = tmparr;
    // 操作tmparr的连续内存，可以通过数组tmparr或tmpptr，并且他们操作方法一致。
    // tmparr的值虽然没有空间保持，但他类型如：const int (*x)[3]
    // tmpptr 类型很明确： int (*x)[3]
    // &tmparr[1]，取数组第一个元素的地址，&tmparr[1]的类型如：const int (*x)[3]。这里可以看出，数组取地址，为数组指针类型！
    // tmparr + 1，也取数组第一个元素的地址，类型如：const int (*x)[3]
    // tmparr[1]是第一个元素，类型：const int *或const int []
    // *(tmparr+1)是第一个元素，类型：const int *或const int []
    // tmparr[1][1]是第一个数组元素的第一个元素，类型：int
    // (tmparr + 1)[1]是第一个数组元素的第一个元素，类型：int
    #define MY_OPT_PTR tmpptr
    logdebugc("init array 2!");
    for (int i = 0; i < MY_CHECK_ROWS; i++)
    {
        for (int j = 0; j < MY_CHECK_COLS; j++)
        {
            // 赋值，第i行，第j列。
            MY_OPT_PTR[i][j] = (i + 1) * (j + 1);
            printf("%03d ", MY_OPT_PTR[i][j]);
        }
        printf("\n");
    }
    for (int i = 0; i < MY_CHECK_ROWS; i++)
    {
        logdebugc("it's [%d] element!", i);
        // 取元素首地址。数组指针类型(int (*x)[3])。 x + 1相差12字节。
        logdebugc("get ptr1:%p", &MY_OPT_PTR[i]);
        // 取元素第一个成员首地址。int指针类型(int *x)。x + 1相差4字节。
        logdebugc("get ptr2:%p", &MY_OPT_PTR[i][0]);
        // 地址+i，获得i个元素首地址。数组指针类型(int (*x)[3])。 x + 1相差12字节。
        logdebugc("get ptr3:%p", MY_OPT_PTR + i);
        // 获得元素成员。
        logdebugc("print val1:%d,%d", MY_OPT_PTR[i][0], MY_OPT_PTR[i][1]);
        logdebugc("print val2:%d,%d", (MY_OPT_PTR + i)[0][0], (MY_OPT_PTR + i)[0][1]);
        logdebugc("print val3:%d,%d", (*(MY_OPT_PTR + i))[0], (*(MY_OPT_PTR + i))[1]);
        logdebugc("print val3:%d,%d", *(*(MY_OPT_PTR + i)), *(*(MY_OPT_PTR + i) + 1));
    }
    return 1;
}
